import { useControlController, useNamespace } from '@ibiz-template/vue3-util';
import { computed, defineComponent, PropType, Ref, ref, watch } from 'vue';
import { ISearchBar } from '@ibiz/model-core';
import { IControlProvider } from '@ibiz-template/runtime';
import { MenuItem } from '@imengyu/vue3-context-menu';
import { isEqual } from 'lodash-es';
import { FilterSearchBarController } from './filter-search-bar.controller';
import {
  GroupName,
  GroupNameLabel,
  ICondition,
  IFilterData,
} from './interface';
import { FilterCond, FilterModal } from './components';
import './filter-search-bar.scss';

export const FilterSearchBarControl = defineComponent({
  name: 'IBizFilterSearchBarControl',
  props: {
    modelData: {
      type: Object as PropType<ISearchBar>,
      required: true,
    },
    context: { type: Object as PropType<IContext>, required: true },
    params: { type: Object as PropType<IParams>, default: () => ({}) },
    provider: { type: Object as PropType<IControlProvider> },
  },
  setup() {
    const c = useControlController(
      (...args) => new FilterSearchBarController(...args),
    );

    const ns = useNamespace(`filter-search-bar`);
    const query: Ref<string> = ref('');
    // UI上维护的非应用中的过滤选中项
    const selection: Ref<string[]> = ref([]);
    // 应用条件是否发生变更
    const condChange: Ref<boolean> = ref(false);
    // UI上维护的应用中的过滤选中项
    const condSelection: Ref<string[]> = ref([]);
    const collapse = ref({ SYS: false, FIELD: false, FILTERLIST: false });

    let ContextMenu: IData;
    c.evt.on('onMounted', () => {
      // 有上下文菜单时加载组件
      const importMenu = () => import('@imengyu/vue3-context-menu');
      importMenu().then(value => {
        ContextMenu = value.default;
        if (ContextMenu.default && !ContextMenu.showContextMenu) {
          ContextMenu = ContextMenu.default;
        }
      });
    });

    // 是否显示按钮
    const visibleButton = computed(() => {
      return (
        selection.value.length > 0 || c.state.applyFilter.condition.length > 0
      );
    });

    watch(
      () => selection.value,
      () => {
        if (condSelection.value.length > 0 && selection.value.length > 0) {
          condChange.value = true;
        } else {
          condChange.value = false;
        }
      },
      {
        deep: true,
      },
    );

    watch(
      () => c.state.applyFilter.condition,
      () => {
        condSelection.value = c.state.applyFilter.condition.map(i => i.id);
      },
    );

    /**
     * 过滤条件发生改变
     */
    const onCondChange = (): void => {
      condChange.value = true;
    };

    /**
     * 显示保存按钮
     */
    const visibleSave = computed(() => {
      let state: boolean = false;
      if (
        !condChange.value &&
        condSelection.value.length > 0 &&
        condSelection.value.length === c.state.applyFilter.condition.length
      ) {
        const oldFilter = c.state.selectGroup!.filter.find(
          f => f.id === c.state.applyFilter.id,
        );
        if (
          !oldFilter ||
          !isEqual(oldFilter.condition, c.state.applyFilter.condition)
        ) {
          state = true;
        }
      }
      return state;
    });

    /**
     * 当前可显示系统过滤项
     */
    const sysFilter = computed(() => {
      return c.state.sysFilter.filter(
        s =>
          s.caption?.includes(query.value) &&
          !c.state.applyFilter.condition.find(a => a.id === s.id),
      );
    });

    /**
     * 当前可显示属性过滤项
     */
    const fieldFilter = computed(() => {
      return c.state.fieldFilter.filter(
        s =>
          s.caption?.includes(query.value) &&
          !c.state.applyFilter.condition.find(a => a.id === s.id),
      );
    });

    /**
     * 当期可显示应用条件
     */
    const condition = computed(() => {
      return c.state.applyFilter.condition.filter(s =>
        s.caption.includes(query.value),
      );
    });

    c._evt.on('onGroupChange', () => {
      condSelection.value = [];
      selection.value = [];
      condChange.value = false;
    });

    /**
     * 清除过滤器
     */
    const onCancel = (): void => {
      condSelection.value = [];
      selection.value = [];
      condChange.value = false;
      c.onClearFilter();
    };

    /**
     * 应用选中条件
     *
     */
    const onConfirm = (): void => {
      const { sysFilter: sys, fieldFilter: field, conds } = c.state;
      const _sys = sys.filter(
        s =>
          selection.value.includes(s.id!) ||
          condSelection.value.includes(s.id!),
      );
      const _field = field.filter(
        s =>
          selection.value.includes(s.id!) ||
          condSelection.value.includes(s.id!),
      );
      const _conds: ICondition[] = [];
      const apply = [..._sys, ..._field];
      apply.forEach(a => {
        _conds.push({
          id: a.id!,
          caption: a.caption!,
          searchconds: conds[a.id!],
        });
      });
      selection.value = [];
      condChange.value = false;
      c.onApplyFilter(_conds);
    };

    /**
     * 改变折叠状态
     *
     * @param {GroupName} name
     */
    const onCollapseChange = (name: GroupName): void => {
      collapse.value[name] = !collapse.value[name];
    };

    /**
     * 打开过滤器右键菜单
     *
     * @param {IFilterData} filter
     * @param {MouseEvent} evt
     */
    const onOpenFilterMenu = (filter: IFilterData, evt: MouseEvent): void => {
      evt.stopPropagation();
      const menus: MenuItem[] = [
        {
          label: '重命名',
          clickClose: true,
          preserveIconWidth: false,
          onClick: (): void => {
            c.onRenameFilter(filter);
          },
        },
        {
          label: '删除',
          clickClose: true,
          preserveIconWidth: false,
          onClick: (): void => {
            c.onRemoveFilter(filter);
          },
        },
      ];
      ContextMenu.showContextMenu({
        x: evt.x,
        y: evt.y,
        customClass: ns.e('actions'),
        items: menus,
      });
    };

    /**
     * 绘制当前应用的过滤条件
     *
     * @return {*}  {JSX.Element}
     */
    const renderFilter = (): JSX.Element => {
      return (
        <div class={ns.e('apply-filter')}>
          <el-checkbox-group v-model={condSelection.value}>
            {condition.value.map(item => {
              return (
                <div class={ns.em('select', 'item')}>
                  <el-checkbox label={item.id!}>{item.caption}</el-checkbox>
                  {condSelection.value.includes(item.id!) && (
                    <FilterCond
                      key={item.id!}
                      id={item.id!}
                      controller={c}
                      onChange={onCondChange}
                    ></FilterCond>
                  )}
                </div>
              );
            })}
          </el-checkbox-group>
        </div>
      );
    };

    /**
     * 绘制可选区
     * - 已保存的过滤器列表
     * - 系统定义的过滤器
     * - 按字段过程
     * @param {GroupName} name
     * @return {*}  {(JSX.Element | undefined)}
     */
    const renderSelectContent = (name: GroupName): JSX.Element | undefined => {
      if (name === 'FILTERLIST') {
        return (
          <div class={ns.em('select', 'filter-list')}>
            {c.state.selectGroup?.filter.map(item => {
              return (
                <div
                  class={[
                    ns.em('select', 'filter'),
                    ns.is('selected', c.state.applyFilter.id === item.id),
                  ]}
                  onClick={() => c.onFilterClick(item)}
                >
                  <span>{item.caption}</span>
                  <el-button
                    text
                    size='small'
                    class={ns.e('hover-action')}
                    onClick={(evt: MouseEvent) => onOpenFilterMenu(item, evt)}
                  >
                    {{
                      icon: () => (
                        <ion-icon name='ellipsis-horizontal-outline' />
                      ),
                    }}
                  </el-button>
                </div>
              );
            })}
          </div>
        );
      }
      const items = name === 'SYS' ? sysFilter.value : fieldFilter.value;
      if (items.length > 0) {
        return (
          <el-checkbox-group v-model={selection.value}>
            {items!.map(item => {
              return (
                <div class={ns.em('select', 'item')}>
                  <el-checkbox label={item.id!}>{item.caption}</el-checkbox>
                  {selection.value.includes(item.id!) && (
                    <FilterCond controller={c} id={item.id!}></FilterCond>
                  )}
                </div>
              );
            })}
          </el-checkbox-group>
        );
      }
      if (query.value) {
        return <div class={ns.em('select', 'no-data')}>--没有匹配的字段--</div>;
      }
    };

    /**
     * 绘制可选的分组
     * @param name
     * @returns
     */
    const renderSelectGroup = (name: GroupName): JSX.Element | undefined => {
      if (
        name !== 'FILTERLIST' ||
        (name === 'FILTERLIST' &&
          c.state.selectGroup &&
          c.state.selectGroup.filter.length > 0)
      ) {
        return (
          <div class={ns.em('select', 'group')}>
            <div
              class={ns.em('select', 'group-name')}
              onClick={() => onCollapseChange(name)}
            >
              {collapse.value[name] ? (
                <ion-icon name='caret-forward-outline' class='icon'></ion-icon>
              ) : (
                <ion-icon name='caret-down-outline' class='icon'></ion-icon>
              )}
              {GroupNameLabel[name]}
            </div>
            {!collapse.value[name] && (
              <div class={ns.em('select', 'group-content')}>
                {renderSelectContent(name)}
              </div>
            )}
          </div>
        );
      }
    };

    /**
     * 绘制底部
     *
     * @return {*}  {(JSX.Element | undefined)}
     */
    const renderFooter = (): JSX.Element | undefined => {
      if (visibleButton.value) {
        return (
          <div class={ns.e('footer')}>
            {visibleSave.value ? (
              <el-button
                class={ns.em('footer', 'save')}
                onClick={() => c.save()}
              >
                保存过滤器
              </el-button>
            ) : (
              <el-button
                class={ns.em('footer', 'confirm')}
                onClick={() => onConfirm()}
              >
                应用过滤器
              </el-button>
            )}
            <el-button
              class={ns.em('footer', 'cancel')}
              onClick={() => onCancel()}
            >
              清空过滤器
            </el-button>
          </div>
        );
      }
    };

    return {
      c,
      ns,
      query,
      sysFilter,
      fieldFilter,
      renderFooter,
      renderFilter,
      renderSelectGroup,
    };
  },
  render() {
    return (
      <iBizControlBase controller={this.c} class={[this.ns.b()]}>
        <div class={this.ns.e('header')}>
          {this.renderSelectGroup('FILTERLIST')}
        </div>
        <div class={this.ns.e('content')}>
          <div class={this.ns.e('search')}>
            {!(ibiz.env as IData).simplemode ? (
              <span class={this.ns.em('search', 'caption')}>
                过滤
                {`${
                  this.c.appDataEntity?.logicName
                    ? this.c.appDataEntity.logicName
                    : ''
                }`}
                通过
              </span>
            ) : null}
            <el-input v-model={this.query} clearable placeholder='搜索'>
              {{
                prefix: () => <ion-icon name='search-outline'></ion-icon>,
              }}
            </el-input>
          </div>
          <div class={this.ns.e('select')}>
            {this.renderFilter()}
            {!(ibiz.env as IData).simplemode
              ? this.renderSelectGroup('SYS')
              : null}
            {this.renderSelectGroup('FIELD')}
          </div>
        </div>
        {this.renderFooter()}
        <FilterModal controller={this.c}></FilterModal>
      </iBizControlBase>
    );
  },
});
